package com.xunge.aop;

import com.xunge.pojo.OperateLog;
import com.xunge.mapper.OperateLogMapper;
import com.xunge.utils.CurrentHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

//import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;

@Slf4j
@Aspect
@Component
public class OperateLogAspect {

    @Autowired
    private OperateLogMapper operateLogMapper;

    // 定义切点：拦截com.xunge.controller包下的所有方法

    @Around("@annotation(com.xunge.anno.Log)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 记录开始时间
        long beginTime = System.currentTimeMillis();

        // 执行目标方法
        Object result = joinPoint.proceed();

        // 记录结束时间
        long endTime = System.currentTimeMillis();
        long costTime = endTime - beginTime;

        // 创建操作日志对象
        OperateLog operateLog = new OperateLog();

        // 设置操作人ID

        operateLog.setOperateEmpId(getOperateEmpId());
        // 设置操作时间
        operateLog.setOperateTime(LocalDateTime.now());
        // 设置类名和方法名
        operateLog.setClassName(joinPoint.getTarget().getClass().getName());
        operateLog.setMethodName(joinPoint.getSignature().getName());
        // 设置方法参数
        Object[] args = joinPoint.getArgs();
        operateLog.setMethodParams(Arrays.toString(args));
        // 设置返回值
        operateLog.setReturnValue(result != null ? result.toString() : "void");
        // 设置执行耗时
        operateLog.setCostTime(costTime);
        // 保存到数据库
        operateLogMapper.insert(operateLog);

        log.info("操作日志：{}", operateLog);
        return result;
    }

    /**
     * 从请求中获取操作人ID
     * 需要根据实际项目的用户认证方式实现
     */

    private Integer getOperateEmpId() {
        // 从当前线程中获取操作人ID
       return CurrentHolder.getCurrentId();
    }
}
